package streams

import (
	"errors"
)

// Number 类型约束
// ~ 波浪号表示衍生类型，即使用 type 自定义的类型也可以被识别到(type MyInt int)，底层类型一致即可
type Number interface {
	~int | ~int64 | ~float64
}

type NumberStream[N Number] interface {
	OrderedStream[N]
	Sum() N
	Max() N
	Min() N
	Avg() float64
}

var _ NumberStream[int] = (*numberStream[int])(nil)

type numberStream[N Number] struct {
	orderedStream[N]
}

func (my *numberStream[N]) Sum() N {
	var sum N = 0
	for _, i := range my.list {
		sum += i
	}
	return sum
}

func (my *numberStream[N]) Max() N {
	if len(my.list) == 0 {
		panic(errors.New("空列表，没有元素"))
	}
	if len(my.list) == 1 {
		return my.list[0]
	}
	maxNum := my.list[0]
	for i := 1; i < len(my.list); i++ {
		cur := my.list[i]
		if maxNum < cur {
			maxNum = cur
		}
	}
	return maxNum
}

func (my *numberStream[N]) Min() N {
	if len(my.list) == 0 {
		panic(errors.New("空列表，没有元素"))
	}
	if len(my.list) == 1 {
		return my.list[0]
	}
	minNum := my.list[0]
	for i := 1; i < len(my.list); i++ {
		cur := my.list[i]
		if minNum > cur {
			minNum = cur
		}
	}
	return minNum
}

func (my *numberStream[N]) Avg() float64 {
	var sum float64 = 0
	for _, i := range my.list {
		sum += float64(i)
	}
	count := len(my.list)
	return sum / float64(count)
}
